<template>
  <div class="home">
    <div>
      <textarea v-model="testAll" id="textarea" style="height: 200px; width: 500px" placeholder="请输入您要合成的文本">
      </textarea>
    </div>
    <div>
      <div>语速([0-100])：<input id="speed" v-model="speed" /></div>
      <div>音量([0-100])：<input id="volume" v-model="volume" /></div>
      <div>音高([0-100])：<input id="pitch" v-model="pitch" /></div>
      <div>发音人：<input id="vcn" value="xiaoyan" /></div>
    </div>
    <div>
      <button v-if="btnStatus == 'UNDEFINED'" @click="start">立即合成</button>
      <button v-else-if="btnStatus == 'CONNECTING'">正在合成</button>
      <button v-else-if="btnStatus == 'PLAY'" @click="stop">停止播放</button>
      <button v-else  @click="replay">重新播放</button>
    </div>
  </div>
</template>

<script>
import CryptoJS from 'crypto-js'
import {Base64} from 'js-base64'

const AudioPlayer = require('../../public/audio.umd')
export default {
  name: 'HomeView',
  data() {
    return {
      testAll:' 春江花月夜春江潮水连海平，海上明月共潮生。滟滟随波千万里，何处春江无月明。江流宛转绕芳甸，月照花林皆似霰。空里流霜不觉飞，汀上白沙看不见。江天一色无纤尘，皎皎空中孤月轮。江畔何人初见月？江月何年初照人？人生代代无穷已，江月年年望相似。不知江月待何人，但见长江送流水。白云一片去悠悠，青枫浦上不胜愁。谁家今夜扁舟子？何处相思明月楼？可怜楼上月徘徊，应照离人妆镜台。玉户帘中卷不去，捣衣砧上拂还来。此时相望不相闻，愿逐月华流照君。鸿雁长飞光不度，鱼龙潜跃水成文。昨夜闲潭梦落花，可怜春半不还家。江水流春去欲尽，江潭落月复西斜。斜月沉沉藏海雾，碣石潇湘无限路。不知乘月几人归，落月摇情满江树。',
      speed: '50',
      volume: '20',
      pitch: '50',
      APPID: 'fe9e9d4f',
      API_SECRET: 'MGFjODUzNjU0YzdkNjM0YjZkZGZlMzU5',
      API_KEY: '926514dd4007649016764a87bb8d09c1',
      btnStatus: 'UNDEFINED', // "UNDEFINED" "CONNECTING" "PLAY" "STOP"
      ttsWS: null,
      audioPlayer: new AudioPlayer('./plugins'),
    }
  },
  methods: {
    start() {
      this.connectWebSocket() // 开始合成
    },
    stop(){
      this.audioPlayer.stop();
      this.changeBtnStatus('STOP')
    },
    replay(){
      this.connectWebSocket()
      this.audioPlayer.play();
      this.changeBtnStatus('PLAY')
    },
    changeBtnStatus(status) {
      this.btnStatus = status
    },
    getWebSocketUrl(apiKey, apiSecret) {
      var url = 'wss://tts-api.xfyun.cn/v2/tts'
      var host = location.host
      var date = new Date().toGMTString()
      var algorithm = 'hmac-sha256'
      var headers = 'host date request-line'
      var signatureOrigin = `host: ${host}\ndate: ${date}\nGET /v2/tts HTTP/1.1`
      var signatureSha = CryptoJS.HmacSHA256(signatureOrigin, apiSecret)
      var signature = CryptoJS.enc.Base64.stringify(signatureSha)
      var authorizationOrigin = `api_key="${apiKey}", algorithm="${algorithm}", headers="${headers}", signature="${signature}"`
      var authorization = btoa(authorizationOrigin)
      url = `${url}?authorization=${authorization}&date=${date}&host=${host}`
      return url
    },
    encodeText(text, type) {
      if (type === 'unicode') {
        let buf = new ArrayBuffer(text.length * 4)
        let bufView = new Uint16Array(buf)
        for (let i = 0, strlen = text.length; i < strlen; i++) {
          bufView[i] = text.charCodeAt(i)
        }
        let binary = ''
        let bytes = new Uint8Array(buf)
        let len = bytes.byteLength
        for (let i = 0; i < len; i++) {
          binary += String.fromCharCode(bytes[i])
        }
        return window.btoa(binary)
      } else {
        return Base64.encode(text)
      }
    },
    connectWebSocket() {
      const url = this.getWebSocketUrl(this.API_KEY, this.API_SECRET)
      if ('WebSocket' in window) {
        this.ttsWS = new WebSocket(url)
      } else if ('MozWebSocket' in window) {
        this.ttsWS = new MozWebSocket(url)
      } else {
        alert('浏览器不支持WebSocket')
        return
      }
      this.changeBtnStatus('CONNECTING')

      this.ttsWS.onopen = e => {
        this.audioPlayer.start({
          autoPlay: true,
          sampleRate: 16000,
          resumePlayDuration: 1000,
        })
        this.changeBtnStatus('PLAY')
        var text = this.testAll
        var tte = 'UTF8'
        var params = {
          common: {
            app_id: this.APPID,
          },
          business: {
            aue: 'raw',
            auf: 'audio/L16;rate=16000',
            vcn: 'xiaoyan',
            speed: parseInt(this.speed) ,
            volume:parseInt(this.volume) ,
            pitch: parseInt(this.pitch),
            bgs: 1,
            tte,
          },
          data: {
            status: 2,
            text: this.encodeText(text, tte),
          },
        }
        this.ttsWS.send(JSON.stringify(params))
      }
      this.ttsWS.onmessage = e => {
        let jsonData = JSON.parse(e.data)
        // 合成失败
        if (jsonData.code !== 0) {
          console.error(jsonData)
          this.changeBtnStatus('UNDEFINED')
          return
        }
        this.audioPlayer.postMessage({
          type: 'base64',
          data: jsonData.data.audio,
          isLastData: jsonData.data.status === 2,
        })
        if (jsonData.code === 0 && jsonData.data.status === 2) {
          this.ttsWS.close()
        }
      }
      this.ttsWS.onerror = e => {
        console.error(e)
      }
      this.ttsWS.onclose = e => {
        // console.log(e);
      }
    },
  },
  mounted() {
    this.audioPlayer.onPlay = () => {
      this.changeBtnStatus('PLAY')
    }
    this.audioPlayer.onStop = audioDatas => {
      console.log(audioDatas)
      this.btnStatus === 'PLAY' && this.changeBtnStatus('STOP')
    }
  },
  components: {},
}
</script>
